﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace Testcraft
{
    class ChunkPart : Physics.PhysicsBody
    {
        private GraphicsDevice device;
        private int vbufferSize;
        private int ibufferSize;
        VertexBuffer vbuffer;
        IndexBuffer ibuffer;

        public int MinY { get; private set; }
        public int MaxY { get; private set; }
        public int NumVertices { get; private set; }
        public int NumPrimitives { get; private set; }
        public int FrameCount { get; set; }

        public VertexBuffer VBuffer { get { return this.vbuffer; } }
        public IndexBuffer IBuffer { get { return this.ibuffer; } }
        public Chunk Chunk { get; private set; }
        public bool IsOccluded { get; set; }

        public List<Block> Blocks { get; private set; }

        public ChunkPart(Chunk chunk, BoundingBox bounds, GraphicsDevice device)
        {
            this.IsOccluded = false;
            this.FrameCount = 0;
            this.Chunk = chunk;
            base.Bounds = bounds;
            base.InRest = true;
            this.device = device;
            this.Blocks = new List<Block>();
            this.vbufferSize = 64 * 16 * 16 * 14;
            this.ibufferSize = (int)(this.vbufferSize * 1.5);
            this.vbuffer = new VertexBuffer(this.device, VertexPositionNormalTexture.VertexDeclaration, this.vbufferSize, BufferUsage.WriteOnly);
            this.ibuffer = new IndexBuffer(this.device, IndexElementSize.ThirtyTwoBits, this.ibufferSize, BufferUsage.WriteOnly);
        }


        public void Update()
        {
            int verticeCount = Block.vertices.Length * this.Blocks.Count;
            this.NumVertices = verticeCount;
            if (this.vbufferSize < verticeCount)
            {
                this.vbufferSize = verticeCount;
                this.vbuffer.Dispose();
                this.vbuffer = new VertexBuffer(this.device, VertexPositionNormalTexture.VertexDeclaration, this.vbufferSize, BufferUsage.WriteOnly);
            }

            VertexPositionNormalTexture[] vertices = new VertexPositionNormalTexture[verticeCount];
            int vertexIndex = 0;
            for (int i = 0; i < this.Blocks.Count; i++)
            {
                Array.Copy(Block.vertices, 0, vertices, vertexIndex, Block.vertices.Length);
                for (int j = 0; j < Block.vertices.Length; j++)
                {

                    vertices[vertexIndex].Position.X += this.Blocks[i].X;
                    vertices[vertexIndex].Position.Y += this.Blocks[i].Y;
                    vertices[vertexIndex++].Position.Z += this.Blocks[i].Z;
                }
            }
            this.vbuffer.SetData<VertexPositionNormalTexture>(vertices);

            int indexCount = this.Blocks.Count * Block.indices.Length;
            this.NumPrimitives = indexCount / 3;
            if (this.ibufferSize < indexCount)
            {
                this.ibufferSize = indexCount;
                this.ibuffer.Dispose();
                this.ibuffer = new IndexBuffer(this.device, IndexElementSize.ThirtyTwoBits, this.ibufferSize, BufferUsage.WriteOnly);
            }

            int[] indices = new int[indexCount];
            int indicesIndex = 0;
            for (int i = 0; i < this.Blocks.Count; i++)
            {
                Array.Copy(Block.indices, 0, indices, indicesIndex, Block.indices.Length);

                for (int j = 0; j < Block.indices.Length; j++)
                {
                    indices[indicesIndex++] += (i * Block.vertices.Length);
                }
            }
            this.ibuffer.SetData<int>(indices);
        }
    }
}
